		TITLE	MOVEFINA - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
if	fgh_win
		INCLUDE	WINMACS
endif

		PUBLIC	MOVE_EXEHDR_TO_FINAL,MOVE_EAX_TO_FINAL_HIGH_WATER,MOVE_EAX_TO_EDX_FINAL


		.DATA

		EXTERNDEF	MAX_FINAL_TABLE:DWORD,MAX_FINAL_RANGES:DWORD,EXEHDR_ADDR:DWORD,FINAL_HIGH_WATER:DWORD
		EXTERNDEF	FINAL_TABLE:DWORD,FINAL_RANGES:DWORD,OS2_EXEHDR_START:DWORD


		.CODE	PASS2_TEXT

		EXTERNDEF	CONVERT_SUBBX_TO_EAX_NOZERO_IO:PROC,DOSPOSITION_A_PER_OUTFILE:PROC,_do_doswrite_release:proc


if	fg_segm

		PUBLIC	MOVE_EAX_TO_EDX_NEXE

MOVE_EAX_TO_EDX_NEXE	PROC
		;
		;
		;
		ADD	EDX,OS2_EXEHDR_START
		JMP	MOVE_EAX_TO_EDX_FINAL

MOVE_EAX_TO_EDX_NEXE	ENDP

endif


MOVE_EXEHDR_TO_FINAL	PROC
		;
		;
		MOV	EDX,EXEHDR_ADDR
		ADD	EXEHDR_ADDR,ECX
		JMP	MOVE_EAX_TO_EDX_FINAL

MOVE_EXEHDR_TO_FINAL	ENDP


MOVE_EAX_TO_FINAL_HIGH_WATER	PROC
		MOV	EDX,FINAL_HIGH_WATER
		JMP	MOVE_EAX_TO_EDX_FINAL
MOVE_EAX_TO_FINAL_HIGH_WATER	ENDP

		public	_move_eax_to_final_high_water
_move_eax_to_final_high_water	proc
		mov	EAX,4[ESP]
		mov	ECX,8[ESP]
		mov	EDX,FINAL_HIGH_WATER
		jmp	MOVE_EAX_TO_EDX_FINAL
_move_eax_to_final_high_water	endp


HELP_RET	PROC

		RET

HELP_RET	ENDP


MOVE_FINAL_TWO	LABEL	PROC

		POPM	ECX,EDX

		XCHG	EAX,ECX

		SUB	EAX,ECX
		PUSH	EDX

		PUSHM	ECX,EAX

		MOV	EAX,ESI
		CALL	MOVE_EAX_TO_EDX_FINAL

		POPM	ECX,EAX,EDX,EDI

		ADD	EDX,EAX
		ADD	EAX,ESI

		POPM	EBX,ESI

MOVE_EAX_TO_EDX_FINAL	PROC
		;
		;EAX IS SOURCE RECORD
		;ECX IS # OF BYTES
		;EDX IS DEST FILE ADDRESS
		;
		TEST	ECX,ECX
		JZ	HELP_RET

		PUSHM	ESI,EBX

		LEA	ESI,[EDX+ECX]
		MOV	EBX,FINAL_HIGH_WATER

		CMP	EBX,ESI
		JA	L02$

		MOV	FINAL_HIGH_WATER,ESI
L02$:
		PUSH	EDI
		MOV	EDI,EDX

		PUSHM	EDX,ECX

		SHR	EDX,PAGE_BITS
		AND	EDI,PAGE_SIZE-1

		MOV	ESI,EAX
		MOV	EAX,PAGE_SIZE

		SUB	EAX,EDI			;CAN WE DO THIS IN ONE MOVE?
		MOV	EBX,OFF FINAL_TABLE-4

		CMP	EAX,ECX
		JC	MOVE_FINAL_TWO		;NOPE, NEED TWO
		;
		;SKIP ANY BLOCKS LESS THAN THIS
		;
L1$:
		MOV	EAX,[EBX+8]
		ADD	EBX,8

		CMP	EAX,EDX
		JB	L1$

		JZ	L2$			;SAME, USE IT...
		;
		;MOVE THESE GUYS UP A STEP
		;
		PUSHM	ESI
		MOV	ESI,MAX_FINAL_TABLE

		PUSHM	EDI,ECX

		LEA	EAX,[ESI+8]
		LEA	EDI,[ESI+4]

		SUB	ESI,4
		MOV	ECX,EDI

		SUB	ECX,EBX
		MOV	MAX_FINAL_TABLE,EAX

		STD

		SHR	ECX,2

		REP	MOVSD

		CLD

		MOV	[EDI],EDX
		MOV	[EDI-4],ECX

		POPM	ECX,EDI,ESI
		;
L2$:
		SUB	EBX,4
		CALL	CONVERT_SUBBX_TO_EAX_NOZERO_IO	;GET ES PTR

		ADD	EDI,EAX
		OPTI_MOVSB

		MOV	EBX,OFF FINAL_RANGES-8
		POPM	ECX,EDX
		;
		;INSTALL THAT RANGE IN TABLE, FLUSH BLOCK IF POSSIBLE
		;
L3$:
		MOV	EAX,[EBX+12]
		ADD	EBX,8

		CMP	EAX,EDX
		JB	L3$		;JUMP IF LARGER

		JNZ	L5$		;GO SEE IF IT MATCHES FRONT

		;
		;THIS MATCHES THAT END-RANGE, SO CHANGE THE END RANGE...
		;
		ADD	EDX,ECX
		MOV	EAX,[EBX+8]

		MOV	[EBX+4],EDX
		;
		;DOES THIS NEW END-RANGE MATCH NEXT BEGINNING RANGE?
		;
		CMP	EAX,EDX
		JNZ	L4$
		;
		;OH BOY! WOWWY DOWWY!
		;
		PUSH	ECX
		MOV	ECX,MAX_FINAL_RANGES

		LEA	ESI,[EBX+12]
		LEA	EDI,[EBX+4]

		SUB	ECX,ESI

		SHR	ECX,2

		REP	MOVSD

		POP	ECX
		MOV	MAX_FINAL_RANGES,EDI
L4$:
		;
		;OK, DID WE COMPLETE A PAGE?
		;
		SUB	EDX,ECX
L41$:
		SHR	EDX,PAGE_BITS
		MOV	EAX,[EBX+4]

		SHR	EAX,PAGE_BITS
		MOV	ECX,[EBX]

		CMP	EDX,EAX
		JNC	L44$			;NOPE, END OF RANGE SAME BLK

		DEC	ECX
		POP	EDI

		SHR	ECX,PAGE_BITS
		POP	EBX

		CMP	EDX,ECX
		JZ	L45$

		POP	ESI
		JMP	FLUSH_EDX

L44$:
		POPM	EDI,EBX
L45$:
		POP	ESI
		RET

L5$:
		;
		;DX:DI IS SMALLER THAN END OF THIS RANGE, MAY NEED TO INSERT
		;A NEW RANGE.
		;
		ADD	EDX,ECX
		MOV	EAX,[EBX]

		CMP	EAX,EDX
		JNZ	L6$
		;
		;MATCH, ADJUST BEGINNING ADDRESS
		;
		SUB	EDX,ECX

		MOV	[EBX],EDX
		JMP	L41$

L6$:
		MOV	ESI,MAX_FINAL_RANGES
		PUSH	ECX

		MOV	ECX,ESI

		LEA	EDI,[ESI+8]
		SUB	ECX,EBX			;BYTES TO MOVE

		MOV	MAX_FINAL_RANGES,EDI
		SUB	ESI,4

		SHR	ECX,2
		SUB	EDI,4

		STD

		REP	MOVSD

		CLD

		POP	ECX
		MOV	[EBX+4],EDX

		SUB	EDX,ECX

		MOV	[EBX],EDX
		JMP	L41$

MOVE_EAX_TO_EDX_FINAL	ENDP

		public _move_eax_to_edx_final
_move_eax_to_edx_final	proc
		mov	EAX,4[ESP]
		mov	ECX,8[ESP]
		mov	EDX,12[ESP]
		jmp	MOVE_EAX_TO_EDX_FINAL
_move_eax_to_edx_final	endp


FLUSH_EDX	PROC	NEAR
		;
		;EDX IS BLOCK BASE OF A BLOCK TO FLUSH OUT...
		;
		;FIND DX IN FINAL_TABLE
		;
		MOV	ECX,OFF FINAL_TABLE-4
		PUSH	EDI

		PUSHM	ESI,EBX
L7$:
		MOV	EAX,[ECX+8]
		ADD	ECX,8

		CMP	EAX,EDX
		JNZ	L7$

		LEA	EDI,[ECX-4]
		LEA	ESI,[ECX+4]

		MOV	ECX,MAX_FINAL_TABLE

		MOV	EAX,[EDI] 		;LOGICAL BLOCK TO WRITE
		SUB	ECX,ESI

		SHR	ECX,2

		REP	MOVSD
		;
		;EAX IS LOGICAL BLOCK, EDX IS TARGET BLOCK ADDRESS
		;
		;EAX MUST BECOME TARGET ADDRESS
		;
		PUSH	EAX
		MOV	EAX,EDX

		SHL	EAX,PAGE_BITS
		MOV	MAX_FINAL_TABLE,EDI

		CALL	DOSPOSITION_A_PER_OUTFILE		;RETURNS EAX == OUT_DEVICE

		POPM	EDX,EBX

		MOV	ECX,PAGE_SIZE
		push	EDX
		push	ECX
		push	EAX
		call	_do_doswrite_release
		add	ESP,12

		YIELD

		POPM	ESI,EDI

		RET

FLUSH_EDX	ENDP


		END

